{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Hello World\n",
    "\n",
    "This guide shows you how to create a \"Hello World\" guardrails configuration that controls the greeting behavior. Before you begin, make sure you have [installed NeMo Guardrails](../../getting_started/installation-guide.md)."
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [],
   "source": [
    "# Init: make sure there is nothing left from a previous run.\n",
    "!rm -r config"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    },
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:02.714612Z",
     "start_time": "2023-11-29T15:38:02.591639Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Prerequisites\n",
    "\n",
    "This \"Hello World\" guardrails configuration uses the OpenAI `gpt-3.5-turbo-instruct` model.\n",
    "\n",
    "1. Install the `openai` package:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "!pip install openai"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "2. Set the `OPENAI_API_KEY` environment variable:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [],
   "source": [
    "!export OPENAI_API_KEY=$OPENAI_API_KEY    # Replace with your own key"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "is_executing": true
    },
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:05.405962Z",
     "start_time": "2023-11-29T15:38:05.281089Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "3. If you're running this inside a notebook, patch the AsyncIO loop."
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "\n",
    "nest_asyncio.apply()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:05.413230Z",
     "start_time": "2023-11-29T15:38:05.406523Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Step 1: create a new guardrails configuration\n",
    "\n",
    "Every guardrails configuration must be stored in a folder. The standard folder structure is as follows:\n",
    "\n",
    "```\n",
    ".\n",
    "├── config\n",
    "│   ├── actions.py\n",
    "│   ├── config.py\n",
    "│   ├── config.yml\n",
    "│   ├── rails.co\n",
    "│   ├── ...\n",
    "```\n",
    "\n",
    "See the [Configuration Guide](../../user_guides/configuration-guide.md) for information about the contents of these files.\n",
    "\n",
    "1. Create a folder, such as *config*, for your configuration:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [],
   "source": [
    "!mkdir config"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:05.545651Z",
     "start_time": "2023-11-29T15:38:05.413342Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "2. Create a *config.yml* file with the following content:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing config/config.yml\n"
     ]
    }
   ],
   "source": [
    "%%writefile config/config.yml\n",
    "models:\n",
    " - type: main\n",
    "   engine: openai\n",
    "   model: gpt-3.5-turbo-instruct"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:05.551931Z",
     "start_time": "2023-11-29T15:38:05.546554Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "The `models` key in the *config.yml* file configures the LLM model. For a complete list of supported LLM models, see [Supported LLM Models](../../user_guides/configuration-guide.md#supported-llm-models)."
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Step 2: load the guardrails configuration"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "To load a guardrails configuration from a path, you must create a `RailsConfig` instance using the `from_path` method in your Python code:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [],
   "source": [
    "from nemoguardrails import RailsConfig\n",
    "\n",
    "config = RailsConfig.from_path(\"./config\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:06.977706Z",
     "start_time": "2023-11-29T15:38:05.550677Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Step 3: use the guardrails configuration\n",
    "\n",
    "Use this empty configuration by creating an `LLMRails` instance and using the `generate_async` method in your Python code:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'role': 'assistant', 'content': \"Hello! It's nice to meet you. My name is Assistant. How can I help you today?\"}\n"
     ]
    }
   ],
   "source": [
    "from nemoguardrails import LLMRails\n",
    "\n",
    "rails = LLMRails(config)\n",
    "\n",
    "response = rails.generate(messages=[{\n",
    "    \"role\": \"user\",\n",
    "    \"content\": \"Hello!\"\n",
    "}])\n",
    "print(response)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:11.926517Z",
     "start_time": "2023-11-29T15:38:06.978037Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "The format for the input `messages` array as well as the response follow the [OpenAI API](https://platform.openai.com/docs/guides/text-generation/chat-completions-api) format.\n",
    "\n",
    "## Step 4: add your first guardrail\n",
    "\n",
    "To control the greeting response, define the user and bot messages, and the flow that connects the two together. See [Core Colang Concepts](../2_core_colang_concepts/README.md) for definitions of *messages* and *flows*.\n",
    "\n",
    "1. Define the `greeting` user message by creating a *config/rails.co* file with the following content:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing config/rails.co\n"
     ]
    }
   ],
   "source": [
    "%%writefile config/rails.co\n",
    "\n",
    "define user express greeting\n",
    "  \"Hello\"\n",
    "  \"Hi\"\n",
    "  \"Wassup?\""
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:11.927899Z",
     "start_time": "2023-11-29T15:38:11.924782Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "2. Add a greeting flow that instructs the bot to respond back with \"Hello World!\" and ask how they are doing by adding the following content to the *rails.co* file:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Appending to config/rails.co\n"
     ]
    }
   ],
   "source": [
    "%%writefile -a config/rails.co\n",
    "\n",
    "define flow greeting\n",
    "  user express greeting\n",
    "  bot express greeting\n",
    "  bot ask how are you"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:11.931926Z",
     "start_time": "2023-11-29T15:38:11.928257Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "3. Define the messages for the response by adding the following content to the *rails.co* file:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Appending to config/rails.co\n"
     ]
    }
   ],
   "source": [
    "%%writefile -a config/rails.co\n",
    "\n",
    "define bot express greeting\n",
    "  \"Hello World!\"\n",
    "\n",
    "define bot ask how are you\n",
    "  \"How are you doing?\""
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:11.937441Z",
     "start_time": "2023-11-29T15:38:11.931634Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "4. Reload the config and test it:"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World!\n",
      "How are you doing?\n"
     ]
    }
   ],
   "source": [
    "config = RailsConfig.from_path(\"./config\")\n",
    "rails = LLMRails(config)\n",
    "\n",
    "response = rails.generate(messages=[{\n",
    "    \"role\": \"user\",\n",
    "    \"content\": \"Hello!\"\n",
    "}])\n",
    "print(response[\"content\"])"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:13.208969Z",
     "start_time": "2023-11-29T15:38:11.934811Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "**Congratulations!** You've just created you first guardrails configuration!"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Other queries\n",
    "\n",
    "What happens if you ask another question, such as \"What is the capital of France?\":"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The capital of France is Paris.\n"
     ]
    }
   ],
   "source": [
    "response = rails.generate(messages=[{\n",
    "    \"role\": \"user\",\n",
    "    \"content\": \"What is the capital of France?\"\n",
    "}])\n",
    "print(response[\"content\"])"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-11-29T15:38:15.125627Z",
     "start_time": "2023-11-29T15:38:13.209729Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "For any other input that is not a greeting, the LLM generates the response as usual. This is because the rail that we have defined is only concerned with how to respond to a greeting."
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## CLI Chat\n",
    "\n",
    "You can also test this configuration in interactive mode using the NeMo Guardrails CLI Chat command:\n",
    "\n",
    "```bash\n",
    "$ nemoguardrails chat\n",
    "```\n",
    "\n",
    "Without any additional parameters, the CLI chat loads the configuration from the *config.yml* file in the *config* folder in the current directory.\n",
    "\n",
    "### Sample session\n",
    "```\n",
    "$ nemoguardrails chat\n",
    "Starting the chat (Press Ctrl+C to quit) ...\n",
    "\n",
    "> Hello there!\n",
    "Hello World!\n",
    "How are you doing?\n",
    "\n",
    "> What is the capital of France?\n",
    "The capital of france is Paris.\n",
    "\n",
    "> And how many people live there?\n",
    "According to the latest estimates, the population of Paris is around 2.2 million people.\n",
    "```"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Server and Chat UI\n",
    "\n",
    "You can also test a guardrails configuration using the NeMo Guardrails server and the Chat UI.\n",
    "\n",
    "To start the server:\n",
    "\n",
    "```bash\n",
    "$ nemoguardrails server --config=.\n",
    "\n",
    "INFO:     Started server process [27509]\n",
    "INFO:     Waiting for application startup.\n",
    "INFO:     Application startup complete.\n",
    "INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\n",
    "```\n",
    "\n",
    "The Chat UI interface is now available at `http://localhost:8000`:\n",
    "\n",
    "![hello-world-server-ui.png](../../_assets/images/hello-world-server-ui.png)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Next\n",
    "\n",
    "The next guide, [Core Colang Concepts](../2_core_colang_concepts/README.md), explains the Colang concepts *messages* and *flows*."
   ],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
